package top.goldenyear.porpoise.framework.web.core.swagger;

import com.github.xiaoymin.knife4j.solon.extension.OpenApiExtensionResolver;
import io.swagger.models.Scheme;
import io.swagger.models.auth.ApiKeyAuthDefinition;
import io.swagger.models.auth.In;
import java.util.function.Predicate;
import org.noear.solon.Solon;
import org.noear.solon.annotation.Bean;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject;
import org.noear.solon.core.BeanWrap;
import org.noear.solon.docs.DocDocket;
import org.noear.solon.docs.models.ApiContact;
import org.noear.solon.docs.models.ApiInfo;

/**
 * @author airhead
 */
@Configuration
public class SwaggerConfig {
  @Inject private OpenApiExtensionResolver openApiExtensionResolver;

  @Bean("adminApi")
  public DocDocket adminApi() {
    DocDocket docDocket =
        new DocDocket()
            .groupName("Admin 端接口")
            .info(
                new ApiInfo()
                    .title("Porpoise")
                    .description("在线API文档")
                    .termsOfService("https://goldsyear.com")
                    .contact(
                        new ApiContact()
                            .name("Porpoise")
                            .url("https://goldsyear.com")
                            .email("l4qiang@hotmail.com"))
                    .version("1.0"))
            .schemes(Scheme.HTTP.toValue())
            .globalResponseInData(true)
            .securityExtensions(
                "token", new ApiKeyAuthDefinition().name("Authorization").in(In.HEADER))
            .vendorExtensions(openApiExtensionResolver.buildExtensions());

    addApis(docDocket, bw -> "adminApi".equals(bw.tag()));

    return docDocket;
  }

  @Bean("appApi")
  public DocDocket appApi() {
    DocDocket docDocket =
        new DocDocket()
            .groupName("App 端接口")
            .info(
                new ApiInfo()
                    .title("Porpoise")
                    .description("在线API文档")
                    .termsOfService("https://goldsyear.com")
                    .contact(
                        new ApiContact()
                            .name("Porpoise")
                            .url("https://goldsyear.com")
                            .email("l4qiang@hotmail.com"))
                    .version("1.0"))
            .schemes(Scheme.HTTP.toValue())
            .globalResponseInData(true)
            .securityExtensions(
                "token", new ApiKeyAuthDefinition().name("Authorization").in(In.HEADER))
            .vendorExtensions(openApiExtensionResolver.buildExtensions());

    addApis(docDocket, bw -> "appApi".equals(bw.tag()));

    return docDocket;
  }

  /**
   * 动态添加包名，参考Gateway.addBeans
   *
   * @param docDocket
   * @param where
   */
  private void addApis(DocDocket docDocket, Predicate<BeanWrap> where) {
    Solon.context()
        .lifecycle(
            () ->
                Solon.context()
                    .beanForeach(
                        bw -> {
                          if (where.test(bw)) {
                            String name = bw.clz().getName();
                            docDocket.apis(name);
                          }
                        }));
  }
}
